package com.mlx.permission.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

public class JavaBean {

    protected Class<?> type;

    protected Map<String, PropertyDescriptor> descriptorMap;

    private JavaBean(Class<?> beanClass){

        this.type = beanClass;

        this.descriptorMap = BeanUtils.getBeanPropertyDescriptorMap(beanClass);
    }

    public static JavaBean build(Class<?> beanClass){
        return new JavaBean(beanClass);
    }

    public Object get(Object bean, String fieldName){
        Method getter = descriptorMap.get(fieldName).getReadMethod();
        if (getter == null){
            throw new RuntimeException(String.format("【%s】类没有【%s】属性", type.toString(), fieldName));
        }

        try {
            return getter.invoke(bean);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(String.format("获取【%s】属性值失败：没有getter方法访问权限", fieldName));
        } catch (InvocationTargetException e) {
            throw new RuntimeException(String.format("获取【%s】属性值失败：getter方法执行时发生异常；异常信息：【%s】", fieldName, e.getMessage()));
        }
    }

    public void set(Object bean, String fieldName, Object value){
        Method setter = descriptorMap.get(fieldName).getWriteMethod();
        if (setter == null){
            throw new RuntimeException(String.format("【%s】类没有【%s】属性", type.toString(), fieldName));
        }
        try {
            setter.invoke(bean, value);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(String.format("设置【%s】属性值失败：没有setter方法访问权限", fieldName));
        } catch (InvocationTargetException e) {
            throw new RuntimeException(String.format("设置【%s】属性值失败：setter方法执行时发生异常；异常信息：【%s】", fieldName, e.getMessage()));
        }
    }

    public Set<String> fieldSet(){
        return descriptorMap.keySet();
    }

    public Class<?> getType() {
        return type;
    }
}
